package cn.gov.pbc.gd.credit.dfs.service.file.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.liu.jbase.ResultVo;
import com.liu.jbase.constant.ResCode;
import com.liu.jbase.service.impl.BaseServiceImpl;
import com.liu.tools.FileUtil;
import com.liu.tools.LogUtil;
import com.liu.tools.PrimaryUtil;
import com.liu.tools.RandomUtil;
import com.liu.tools.StrUtil;

import cn.gov.pbc.gd.credit.api.file.IFileApi;
import cn.gov.pbc.gd.credit.common.constant.CodeConstant;
import cn.gov.pbc.gd.credit.common.constant.CommonConstant;
import cn.gov.pbc.gd.credit.common.constant.ConfConstant;
import cn.gov.pbc.gd.credit.common.model.UserModel;
import cn.gov.pbc.gd.credit.common.service.redis.IRedisService;
import cn.gov.pbc.gd.credit.common.util.UserUtil;
import cn.gov.pbc.gd.credit.dfs.service.file.IFileService;
import cn.gov.pbc.gd.credit.vo.file.FileVo;
import cn.gov.pbc.gd.credit.vo.file.ResFileVo;

@Service
public class FileServiceImpl extends BaseServiceImpl<ResFileVo, FileVo, IFileApi> implements IFileService{

	private static Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);
	
	@Autowired
	private IFileApi fileApi;
	
	@Autowired
	private IRedisService redisService;
	
	@Override
	public ResultVo<ResFileVo> add(FileVo record, HttpServletRequest request) {
		
		ResultVo<ResFileVo> resultVo = new ResultVo<>();
		
		MultipartFile file = record.getFile();
		
		if(file == null){
			resultVo.setCode(ResCode.REQ_PARAM_FAIL);
			resultVo.setMsg("文件为空");
			logger.error(LogUtil.msg("FileServiceImpl:add", record.getSid(), "文件为空", record.getIp()));
			return resultVo;
		}
		
		String fileName = file.getOriginalFilename();
		logger.info(LogUtil.msg("FileServiceImpl:add", record.getSid(), "文件名称：" + fileName, record.getIp()));
		String filePath = ConfConstant.fileStorePathCommon;
		if(CommonConstant.FILE_SOURCE_TYPE_QUERY == record.getSourceType()){
			filePath = ConfConstant.fileStorePathInquiry;
		}
		
		String relFilePath = RandomUtil.randomStr(1, RandomUtil.NUM_CHAR) + File.separator;
		relFilePath += RandomUtil.randomStr(1, RandomUtil.NUM_CHAR) + File.separator;
		
		String fileId = PrimaryUtil.primaryId("F");
		String suffix = FileUtil.getFileNameSuffix(fileName);
		filePath += relFilePath;
		
		try {
			FileUtil.createDir(filePath);
			FileUtil.writeFile(file.getInputStream(), filePath + fileId + suffix);
		} catch (Exception e) {
			logger.error(LogUtil.msg("FileServiceImpl:add", record.getSid(), "创建文件失败", record.getIp()), e);
			resultVo.setCode(ResCode.EXCEPTION);
			resultVo.setMsg("存储文件数据失败");
			return resultVo;
		} 
		if(".jpg,.png,.bmp,.jpeg".indexOf(suffix) != -1){
			record.setFileType(1);
		} else {
			record.setFileType(2);
		}
		
		UserModel userModel = UserUtil.getUserModel(record.getSid(), redisService);
		
		record.setStatus(1);
		record.setSuffix(suffix);
		record.setFilePath(relFilePath);
		record.setFileName(file.getOriginalFilename());
		record.setFileSize(file.getSize());
		record.setId(fileId);
		record.setVirtualId(record.getId());
		record.setSvrAddr(ConfConstant.fileSvrAddr);
		record.setUpdateBy(userModel.getUserId());
		record.setUpdateTime(new Date());
		record.setCreateBy(userModel.getUserId());
		record.setCreateTime(new Date());
		record.setUseCount(1);
		record.setFile(null);
		record.setFiles(null);
		
		try {
			fileApi.insert(record);
		} catch (Exception e) {
			logger.error(LogUtil.msg("FileServiceImpl:add", record.getSid(), "添加文件信息异常", record.getIp()), e);
			resultVo.setCode(ResCode.EXCEPTION);
			resultVo.setMsg("存储文件信息失败");
			return resultVo;
		}
		
		ResFileVo resFileVo = new ResFileVo();
		resFileVo.setId(record.getId());
		resultVo.setData(resFileVo);
		resultVo.setCode(CodeConstant.SUCCESS);
		return resultVo;
	}

	@Override
	public ResultVo<ResFileVo> download(FileVo vo, HttpServletRequest request, HttpServletResponse response) {

		ResultVo<ResFileVo> resultVo = new ResultVo<>();
		
		if(vo == null || StrUtil.isNull(vo.getId())){
			resultVo.setCode(CodeConstant.REQ_PARAM_FAIL);
			logger.error(LogUtil.msg("FileServiceImpl:add", vo.getSid(), "请求参数正确", vo.getIp()));
			resultVo.setMsg("文件id不能为空");
			return resultVo;
		}
		
		ResFileVo resFileVo = fileApi.queryById(vo.getId());
		
		if(resFileVo == null){
			
			resultVo.setCode(CodeConstant.DATA_NOT_EXSIT);
			logger.error(LogUtil.msg("FileServiceImpl:add", vo.getSid(), "文件不存在", JSON.toJSONString(vo)));
			resultVo.setMsg("文件不存在");
			return resultVo;
		}
		
		String filePath = ConfConstant.fileStorePathCommon;
		if(CommonConstant.FILE_SOURCE_TYPE_QUERY == resFileVo.getSourceType()){
			filePath = ConfConstant.fileStorePathInquiry;
		}
		
		filePath += resFileVo.getFilePath() + resFileVo.getId() + resFileVo.getSuffix(); 
		
		logger.debug(LogUtil.msg("FileServiceImpl:add", "文件地址：" + filePath));
		
		response.setCharacterEncoding("utf-8");  
        response.setContentType("multipart/form-data");  
        response.setHeader("Content-Disposition", "attachment;fileName=" + resFileVo.getFileName());  
        
        try {  

            InputStream inputStream = new FileInputStream(new File(filePath));  
  
            OutputStream os = response.getOutputStream();  
            byte[] b = new byte[2048];  
            int length;  
            while ((length = inputStream.read(b)) > 0) {  
                os.write(b, 0, length);  
            }  
             // 这里主要关闭。  
            os.close();  
  
            inputStream.close();  
            
        } catch (FileNotFoundException e) {  
        	logger.error(LogUtil.msg("FileServiceImpl:add", vo.getSid(), "获取文件异常"), e);
        } catch (IOException e) {  
        	logger.error(LogUtil.msg("FileServiceImpl:add", vo.getSid(), "获取文件异常"), e);  
        }  
        
        resultVo.setCode(CodeConstant.SUCCESS);
        
        return resultVo;   
		
	}

	@Override
	public ResultVo<String> getFilePath(FileVo vo, HttpServletRequest request) {

		ResultVo<String> resultVo = new ResultVo<>();
		
		if(vo == null || StrUtil.isNull(vo.getId())){
			resultVo.setCode(CodeConstant.REQ_PARAM_FAIL);
			logger.error(LogUtil.msg("FileServiceImpl:add", vo.getSid(), "请求参数正确", vo.getIp()));
			resultVo.setMsg("文件id不能为空");
			return resultVo;
		}
		
		ResFileVo resFileVo = fileApi.queryById(vo.getId());
		
		if(resFileVo == null){
			
			resultVo.setCode(CodeConstant.DATA_NOT_EXSIT);
			logger.error(LogUtil.msg("FileServiceImpl:add", vo.getSid(), "文件不存在", JSON.toJSONString(vo)));
			resultVo.setMsg("文件不存在");
			return resultVo;
		}
		
		String filePath = ConfConstant.fileStorePathCommon;
		if(CommonConstant.FILE_SOURCE_TYPE_QUERY == resFileVo.getSourceType()){
			filePath = ConfConstant.fileStorePathInquiry;
		}
		
		filePath += resFileVo.getFilePath() + resFileVo.getId() + resFileVo.getSuffix(); 
		
		logger.debug(LogUtil.msg("FileServiceImpl:add", "文件地址：" + filePath));
        
        resultVo.setCode(CodeConstant.SUCCESS);
        resultVo.setData(filePath);
        
        return resultVo; 
	}

	@Override
	public ResultVo<List<ResFileVo>> addBase64File(FileVo vo, HttpServletRequest request) {

		ResultVo<List<ResFileVo>> resultVo = new ResultVo<>();
		
		List<String> base64Files = vo.getBase64Files();
		
		if(base64Files == null || base64Files.size() == 0){
			resultVo.setCode(ResCode.REQ_PARAM_FAIL);
			resultVo.setMsg("文件为空");
			logger.error(LogUtil.msg("FileServiceImpl:addBase64File", vo.getSid(), "文件为空", vo.getIp()));
			return resultVo;
		}
		
		UserModel userModel = UserUtil.getUserModel(vo.getSid(), redisService);
		
		List<ResFileVo> list = new ArrayList<>();
		
		for (String base64File : base64Files) {
			
			String fileId = PrimaryUtil.primaryId("F");
			String fileName = "gpy_" + fileId + ".jpg";
			logger.info(LogUtil.msg("FileServiceImpl:addBase64File", vo.getSid(), "文件名称：" + fileName, vo.getIp()));
			String filePath = ConfConstant.fileStorePathCommon;
			if(CommonConstant.FILE_SOURCE_TYPE_QUERY == vo.getSourceType()){
				filePath = ConfConstant.fileStorePathInquiry;
			}
			
			String relFilePath = RandomUtil.randomStr(1, RandomUtil.NUM_CHAR) + File.separator;
			relFilePath += RandomUtil.randomStr(1, RandomUtil.NUM_CHAR) + File.separator;
			
			
			String suffix = FileUtil.getFileNameSuffix(fileName);
			filePath += relFilePath;
			long fileSize = 0;
			try {
				
				FileUtil.createDir(filePath);
				fileSize = FileUtil.base64ToImage(base64File, filePath + fileId + suffix);
			} catch (Exception e) {
				logger.error(LogUtil.msg("FileServiceImpl:addBase64File", vo.getSid(), "创建文件失败", vo.getIp()), e);
				resultVo.setCode(ResCode.EXCEPTION);
				resultVo.setMsg("存储文件数据失败");
				return resultVo;
			} 
			if(".jpg,.png,.bmp,.jpeg".indexOf(suffix) != -1){
				vo.setFileType(1);
			} else {
				vo.setFileType(2);
			}
			
			vo.setStatus(1);
			vo.setSuffix(suffix);
			vo.setFilePath(relFilePath);
			vo.setFileName(fileName);
			vo.setFileSize(fileSize);
			vo.setId(fileId);
			vo.setVirtualId(vo.getId());
			vo.setSvrAddr(ConfConstant.fileSvrAddr);
			vo.setUpdateBy(userModel.getUserId());
			vo.setUpdateTime(new Date());
			vo.setCreateBy(userModel.getUserId());
			vo.setCreateTime(new Date());
			vo.setUseCount(1);
			vo.setFile(null);
			vo.setFiles(null);
			
			try {
				fileApi.insert(vo);
			} catch (Exception e) {
				logger.error(LogUtil.msg("FileServiceImpl:addBase64File", vo.getSid(), "添加文件信息异常", vo.getIp()), e);
				resultVo.setCode(ResCode.EXCEPTION);
				resultVo.setMsg("存储文件信息失败");
				return resultVo;
			}
			
			ResFileVo resFileVo = new ResFileVo();
			resFileVo.setId(vo.getId());
			list.add(resFileVo);
			
		}
		
		resultVo.setCode(CodeConstant.SUCCESS);
		resultVo.setData(list);
		return resultVo;
	}
	
	
}
